import {ObjectID} from "mongodb";
import {Promise} from 'es6-promise';
import PWSApp from "../../core/app";
import HomeBaseAction from "./act.base";
import {Magics} from "../../core/magics";
import {ModList} from "../../core/types";
import {Request, Response} from "express";
import * as utils from '../../core/utils';
import {RouteType} from "../../core/defines";
import {ErrCode} from "../../core/error.code";
import {MongoColls} from "../../config/mongo";
import CartModel, {
    UserCart,
} from "../../models/mod.cart";
import ProductModel, {
    ProductInfo,
} from "../../models/mod.product";


export default class CartAction extends HomeBaseAction {

    name() {
        return `${this.app.name}CartAction`;
    }

    private _cartMod: CartModel;
    private _productMod: ProductModel;

    constructor(app: PWSApp) {
        super(app);
        this._cartMod = new CartModel(this.db.collection(MongoColls.CART));
        this._productMod = new ProductModel(this.db.collection(MongoColls.PRODUCT));
    }

    protected _setRoutes() {
        this._setRoot('/api/cart'); //need login
        this._route(RouteType.POST, '/add', this._actAddToCart);
        this._route(RouteType.POST, '/del', this._actDeleteCart);
        this._route(RouteType.GET, '/list/:page', this._actGetCartList);
    }

    private _actAddToCart(req: Request, res: Response) {
        let {prod_id, num} = req.body;
        Promise.resolve().then(() => {
            if (!utils.isObjectId(prod_id) || !utils.isPositiveNum(num)) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            let filter = {_id: utils.toObjectId(prod_id)};
            return this._productMod.checkExist(filter);
        }).then((prod: ProductInfo) => {
            if(!prod){
                return Promise.reject({err_code: ErrCode.ProdNotFound});
            }
            let sess = req.session[Magics.SessUser] || {};
            let user_id: ObjectID = utils.toObjectId(sess['_id']);

            let filter = {
                user_id,
                prod_id: prod._id
            };
            let card: UserCart = {
                user_id: user_id,
                prod_id: prod._id,
                shop_id: prod.shop.id,
                num: utils.toInt(num)
            };
            return this._cartMod.addToCart(filter, card);
        }).then(() => {
            res.send({err_code: ErrCode.Success});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actDeleteCart(req: Request, res: Response) {

        Promise.resolve().then(() => {
            let {id} = req.body;
            if (!utils.isObjectId(id)) {
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }
            let match = {_id: utils.toObjectId(id)};
            return this._cartMod.deleteCart(match);
        }).then(() => {
            res.send({err_code: ErrCode.Success});
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

    private _actGetCartList(req: Request, res: Response) {
        Promise.resolve().then(() => {
            let {page} = req.params;
            let sessUser = req.session[Magics.SessUser] || {};
            let curPage = utils.isPositiveNum(page) ? utils.toInt(page) : 0;
            let filter = {
                user_id: utils.toObjectId(sessUser['_id']),
                page: curPage,
                limit: 20
            };
            return this._cartMod.getCarts(filter);
        }).then((data: ModList) => {
            let {limit, curr_page, total_count, records, total_page} = data;
            let result = {
                limit, curr_page, total_count, total_page,
                carts: records,
                err_code: ErrCode.Success
            };
            res.send(result);
        }).catch((err) => {
            this._errHandler(req, res, err);
        });
    }

}